--- /dev/null
+/* babl - dynamically extendable universal pixel conversion library.
+ * Copyright (C) 2012, Øyvind Kolås
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "babl-internal.h"
+#include "babl-cpuaccel.h"
+#include "extensions/util.h"
+#include "base/util.h"
+
+
+#define INLINE inline
+
+
+static INLINE void
+conv_rgbaD_linear_rgbAD_gamma (const Babl *conversion,unsigned char *src,
+ unsigned char *dst,
+ long samples)
+{
+ const Babl *space = babl_conversion_get_destination_space (conversion);
+ const Babl **trc = (void*)space->space.trc;
+
+ double *fsrc = (double *) src;
+ double *fdst = (double *) dst;
+ int n = samples;
+
+ while (n--)
+ {
+ double alpha = fsrc[3];
+ *fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * alpha;
+ *fdst++ = babl_trc_from_linear (trc[1], *fsrc++) * alpha;
+ *fdst++ = babl_trc_from_linear (trc[2], *fsrc++) * alpha;
+ *fdst++ = *fsrc++;
+ }
+}
+
+static INLINE void
+conv_rgbAD_linear_rgbAD_gamma (const Babl *conversion,
+ unsigned char *src,
+ unsigned char *dst,
+ long samples)
+{
+ const Babl *space = babl_conversion_get_destination_space (conversion);
+ const Babl **trc = (void*)space->space.trc;
+
+ double *fsrc = (double *) src;
+ double *fdst = (double *) dst;
+ int n = samples;
+
+ while (n--)
+ {
+ double alpha = fsrc[3];
+ if (alpha < BABL_ALPHA_THRESHOLD)
+ {
+ *fdst++ = 0.0;
+ *fdst++ = 0.0;
+ *fdst++ = 0.0;
+ *fdst++ = 0.0;
+ fsrc+=4;
+ }
+ else if (alpha >= 1.0)
+ {
+ *fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * alpha;
+ *fdst++ = babl_trc_from_linear (trc[1], *fsrc++) * alpha;
+ *fdst++ = babl_trc_from_linear (trc[2], *fsrc++) * alpha;
+ *fdst++ = *fsrc++;
+ }
+ else
+ {
+ double alpha_recip = 1.0 / alpha;
+ *fdst++ = babl_trc_from_linear (trc[0], *fsrc++ * alpha_recip) * alpha;
+ *fdst++ = babl_trc_from_linear (trc[1], *fsrc++ * alpha_recip) * alpha;
+ *fdst++ = babl_trc_from_linear (trc[2], *fsrc++ * alpha_recip) * alpha;
+ *fdst++ = *fsrc++;
+ }
+ }
+}
+
+static INLINE void
+conv_rgbaD_linear_rgbaD_gamma (const Babl *conversion,unsigned char *src,
+ unsigned char *dst,
+ long samples)
+{
+ const Babl *space = babl_conversion_get_destination_space (conversion);
+ const Babl **trc = (void*)space->space.trc;
+
+ double *fsrc = (double *) src;
+ double *fdst = (double *) dst;
+ int n = samples;
+
+ while (n--)
+ {
+ *fdst++ = babl_trc_from_linear (trc[0], *fsrc++);
+ *fdst++ = babl_trc_from_linear (trc[1], *fsrc++);
+ *fdst++ = babl_trc_from_linear (trc[2], *fsrc++);
+ *fdst++ = *fsrc++;
+ }
+}
+
+#define conv_rgbaD_linear_rgbD_linear conv_rgbaD_gamma_rgbD_gamma
+
+static void
+conv_rgbaD_linear_rgbD_linear (const Babl *conversion,unsigned char *src,
+ unsigned char *dst,
+ long samples)
+{
+ double *fsrc = (double *) src;
+ double *fdst = (double *) dst;
+ int n = samples;
+
+ while (n--)
+ {
+ *fdst++ = *fsrc++;
+ *fdst++ = *fsrc++;
+ *fdst++ = *fsrc++;
+ fsrc++;
+ }
+}
+
+
+static INLINE void
+conv_rgbD_linear_rgbD_gamma (const Babl *conversion,unsigned char *src,
+ unsigned char *dst,
+ long samples)
+{
+ const Babl *space = babl_conversion_get_destination_space (conversion);
+ const Babl **trc = (void*)space->space.trc;
+ double *fsrc = (double *) src;
+ double *fdst = (double *) dst;
+ int n = samples;
+
+ while (n--)
+ {
+ *fdst++ = babl_trc_from_linear (trc[0], *fsrc++);
+ *fdst++ = babl_trc_from_linear (trc[1], *fsrc++);
+ *fdst++ = babl_trc_from_linear (trc[2], *fsrc++);
+ }
+}
+
+
+static INLINE void
+conv_rgbaD_gamma_rgbaD_linear (const Babl *conversion,unsigned char *src,
+ unsigned char *dst,
+ long samples)
+{
+ const Babl *space = babl_conversion_get_destination_space (conversion);
+ const Babl **trc = (void*)space->space.trc;
+ double *fsrc = (double *) src;
+ double *fdst = (double *) dst;
+ int n = samples;
+
+ while (n--)
+ {
+ *fdst++ = babl_trc_to_linear (trc[0], *fsrc++);
+ *fdst++ = babl_trc_to_linear (trc[1], *fsrc++);
+ *fdst++ = babl_trc_to_linear (trc[2], *fsrc++);
+ *fdst++ = *fsrc++;
+ }
+}
+
+static INLINE void
+conv_rgbD_gamma_rgbD_linear (const Babl *conversion,unsigned char *src,
+ unsigned char *dst,
+ long samples)
+{
+ const Babl *space = babl_conversion_get_destination_space (conversion);
+ const Babl **trc = (void*)space->space.trc;
+ double *fsrc = (double *) src;
+ double *fdst = (double *) dst;
+ int n = samples;
+
+ while (n--)
+ {
+ *fdst++ = babl_trc_to_linear (trc[0], *fsrc++);
+ *fdst++ = babl_trc_to_linear (trc[1], *fsrc++);
+ *fdst++ = babl_trc_to_linear (trc[2], *fsrc++);
+ }
+}
+
+#define o(src, dst) \
+ babl_conversion_new (src, dst, "linear", conv_ ## src ## _ ## dst, NULL)
+
+int init (void);
+
+int
+init (void)
+{
+ const Babl *rgbaD_linear = babl_format_new (
+ babl_model ("RGBA"),
+ babl_type ("double"),
+ babl_component ("R"),
+ babl_component ("G"),
+ babl_component ("B"),
+ babl_component ("A"),
+ NULL);
+ const Babl *rgbAD_linear = babl_format_new (
+ babl_model ("RaGaBaA"),
+ babl_type ("double"),
+ babl_component ("Ra"),
+ babl_component ("Ga"),
+ babl_component ("Ba"),
+ babl_component ("A"),
+ NULL);
+ const Babl *rgbaD_gamma = babl_format_new (
+ babl_model ("R'G'B'A"),
+ babl_type ("double"),
+ babl_component ("R'"),
+ babl_component ("G'"),
+ babl_component ("B'"),
+ babl_component ("A"),
+ NULL);
+ const Babl *rgbAD_gamma = babl_format_new (
+ babl_model ("R'aG'aB'aA"),
+ babl_type ("double"),
+ babl_component ("R'a"),
+ babl_component ("G'a"),
+ babl_component ("B'a"),
+ babl_component ("A"),
+ NULL);
+ const Babl *rgbD_linear = babl_format_new (
+ babl_model ("RGB"),
+ babl_type ("double"),
+ babl_component ("R"),
+ babl_component ("G"),
+ babl_component ("B"),
+ NULL);
+ const Babl *rgbD_gamma = babl_format_new (
+ babl_model ("R'G'B'"),
+ babl_type ("double"),
+ babl_component ("R'"),
+ babl_component ("G'"),
+ babl_component ("B'"),
+ NULL);
+
+ o (rgbAD_linear, rgbAD_gamma);
+ o (rgbaD_linear, rgbAD_gamma);
+ o (rgbaD_linear, rgbaD_gamma);
+ o (rgbaD_gamma, rgbaD_linear);
+ o (rgbD_linear, rgbD_gamma);
+ o (rgbD_gamma, rgbD_linear);
+ o (rgbaD_linear, rgbD_linear);
+ o (rgbaD_gamma, rgbD_gamma);
+
+ return 0;
+}
+
#define conv_gA16_gAF conv_ga16_gaF
#define conv_g16_gF conv_16_F
+static void
+conv_rgbafloat_linear_cairo32_le (const Babl *conversion,unsigned char *src_char,
+ unsigned char *dst,
+ long samples)
+{
+ long n = samples;
+ float *src = (float*)src_char;
+
+ while (n--)
+ {
+ float alpha = src[3] * 255;
+#define BABL_ALPHA_THRESHOLD 0.000000152590219
+
+ if (alpha < BABL_ALPHA_THRESHOLD)
+ {
+ *(int *)dst = 0;
+ }
+ else
+ {
+ if (alpha > 255) alpha = 255;
+#define div_255(a) ((((a)+128)+(((a)+128)>>8))>>8)
+ dst[0] = src[2] * alpha + 0.5f;
+ dst[1] = src[1] * alpha + 0.5f;
+ dst[2] = src[0] * alpha + 0.5f;
+ dst[3] = alpha + 0.5f;
+ }
+ src += 4;
+ dst += 4;
+ }
+}
+
+
int init (void);
int
babl_component ("Y"),
NULL);
+ int testint = 23;
+ char *testchar = (char*) &testint;
+ int littleendian = (testchar[0] == 23);
+
+ if (littleendian)
+ {
+ const Babl *f32 = babl_format_new (
+ "name", "cairo-ARGB32",
+ babl_model ("R'aG'aB'aA"),
+ babl_type ("u8"),
+ babl_component ("B'a"),
+ babl_component ("G'a"),
+ babl_component ("R'a"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_conversion_new (babl_format ("RGBA float"), f32, "linear",
+ conv_rgbafloat_linear_cairo32_le, NULL);
+ }
+
#define o(src, dst) \
babl_conversion_new (src, dst, "linear", conv_ ## src ## _ ## dst, NULL)